package com.mate.cloud.redisson.service;

import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RBatch;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ProductTagService {

    private final RedissonClient redissonClient;

    private String productTagsKey(String productId) {
        return "product:" + productId + ":tags";
    }

    private String tagProductsKey(String tagId) {
        return "tag:" + tagId + ":products";
    }

    /**
     * 商品添加标签
     */
    public void addTag(String productId, String tagId) {
        RBatch batch = redissonClient.createBatch();
        batch.getSet(productTagsKey(productId)).addAsync(tagId);
        batch.getSet(tagProductsKey(tagId)).addAsync(productId);
        batch.execute();
    }

    /**
     * 商品移除标签
     */
    public void removeTag(String productId, String tagId) {
        RBatch batch = redissonClient.createBatch();
        batch.getSet(productTagsKey(productId)).removeAsync(tagId);
        batch.getSet(tagProductsKey(tagId)).removeAsync(productId);
        batch.execute();
    }

    /**
     * 获取商品的所有标签
     */
    public Set<String> getTagsByProduct(String productId) {
        return redissonClient.getSet(productTagsKey(productId)).readAll()
                .stream()
                .map(String::valueOf)
                .collect(Collectors.toSet());
    }

    /**
     * 获取某标签下的商品
     */
    public Set<String> getProductsByTag(String tagId) {
        return redissonClient.getSet(tagProductsKey(tagId)).readAll()
                .stream()
                .map(String::valueOf)
                .collect(Collectors.toSet());
    }

    /**
     * 查询多个标签下的交集商品
     */
    public Set<String> getProductsByTags(Set<String> tagIds) {

        if (tagIds.isEmpty()) return Collections.emptySet();
        Iterator<String> it = tagIds.iterator();
        RSet<String> base = redissonClient.getSet(tagProductsKey(it.next()));
        List<String> others = Lists.newArrayList();
        while (it.hasNext()) {
            others.add(tagProductsKey(it.next()));
        }
        return base.readIntersection(others.toArray(new String[0]));
    }
}
